package com.bkbw.live.battle.actor;

import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import jdk.nashorn.internal.ir.RuntimeNode.Request;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import scala.util.parsing.combinator.PackratParsers.Head;

import com.badlogic.gdx.ai.GdxAI;
import com.bkbw.live.battle.bean.CharManager;
import com.bkbw.live.battle.bean.CharManager.CharacterInfo;
import com.bkbw.live.battle.net.codec.PackageHead;

import akka.actor.Actor;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.actor.UntypedActorFactory;

import com.bkbw.live.common.GameConfig;
import com.bkbw.live.common.dataproto.BattleToDatabasePb.DB2BSBuyItemResp;
import com.bkbw.live.common.dataproto.BattleToDatabasePb.DB2BSCharacterResp;
import com.bkbw.live.common.dataproto.BattleToDatabasePb.DB2BSDropBagItemResp;
import com.bkbw.live.common.dataproto.BattleToDatabasePb.DB2BSEquipResp;
import com.bkbw.live.common.dataproto.BattleToDatabasePb.DB2BSUseBagItemResp;
import com.bkbw.live.common.dataproto.ClientToBattleServerPb;
import com.bkbw.live.common.dataproto.ClientToBattleServerPb.*;
import com.bkbw.live.battle.net.message.MessageObject;

public class TableActorManager extends UntypedActor{
	
	Logger logger = LoggerFactory.getLogger(GameConfig.LoggerName);
	
	//房间列表,key:房间id  value：房间的Actor对象
	private Map<Integer,ActorRef> tables = new HashMap<Integer, ActorRef>();
	//存储用户在哪个房间key 用户id  value:房间id
	private Map<Integer,Integer> user_table = new HashMap<Integer, Integer>();
	
	ActorRef findPathActor;
	
	public TableActorManager() {
		// TODO Auto-generated constructor stub
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			long lastTime = System.nanoTime();
			@Override
			public void run() {
				long now = System.nanoTime();
				float dt = (float)((now - lastTime)*0.000000001D);
				//System.out.println("dt is "+dt);
				lastTime = now;
				GdxAI.getTimepiece().update(dt);
				for (Integer key : tables.keySet()) {
					ActorRef table = tables.get(key);
					table.tell("loop");
				}
			}
		}, 0, 50);
		
		findPathActor = this.getContext().actorOf(new Props(new UntypedActorFactory() {
            public UntypedActor create() {
                //return new TableActor(tableId);
            	return new AsyncFindPathActor(TableActorManager.this.getSelf());
            }
        }),"pathfinder");
		
		/*Thread thread = new Thread(new Runnable() {
			long last = 0;
			long current = 0;
			int count = 0;
			@Override
			public void run() {
				
				// TODO Auto-generated method stub
				try {
					current = System.nanoTime();
					System.out.println("thread time diff nanosec " + (current - last));
					count++;
					if (count % 5 == 0) {
						for (ActorRef table : tables.values()) {
							table.tell("loop");
						}
					}
					int diff = (int)(System.nanoTime() - current);
					
					System.out.println("update execute nanosec " + diff);
					Thread.sleep(10, 0);
					last = current;
				}
				catch (Exception e){
					
				}
			}
		});
		thread.start();*/
	}
	
	
	@Override
	public void onReceive(Object arg0)  {
	//  it's better not throw exception to akka
		try {
			if(arg0 instanceof MessageObject){
				MessageObject mo = (MessageObject) arg0;
				//玩家进入房间
				switch (mo.getHead()) {
				case HeadType.DUNGON_LOGIN_REQ_VALUE:
				{
					//取出房间id，如果房间不存在，就开一个新房间，存在则把这个消息直接告知房间
					ClientToBattleServerPb.LoginReq req = (ClientToBattleServerPb.LoginReq) mo.getData();
					int tableId = req.getAllianceId();
					System.out.println("玩家"+req.getUserId()+"进房间"+req.getAllianceId());
					ActorRef table = null;
					if(!tables.containsKey(tableId)){
						//用工会id作为房间的id来开副本
						table = this.getContext().actorOf(new Props(new UntypedActorFactory() {
				            public UntypedActor create() {
				                //return new TableActor(tableId);
				            	return new BattleActor(tableId, TableActorManager.this.getSelf());
				            }
						})); // 匿名
				        //}),"battle"+tableId);
						tables.put(tableId, table);//保存房间
					}else{
						table = tables.get(tableId);
					}
					CharManager.getInstance().addCharacter(req.getUserId(), mo.getSession());
					CharManager.getInstance().getCharacter(req.getUserId()).setTableId(tableId);
					//保存用户在哪个房间中
					user_table.put(req.getUserId(), tableId);
					//把这个消息告诉房间
					table.tell(mo);
					break;
				}
				case HeadType.DUNGON_PLAYER_MOVE_VALUE:
				{
					ClientToBattleServerPb.Move mov = (ClientToBattleServerPb.Move) mo.getData();
					int tableId = mov.getTableId();
					if (tables.containsKey(tableId)) {
						tables.get(tableId).tell(mo);
					}
//					
//					int userId = mov.getId();
//					//把这个消息发到用户所在的房间
//					if(user_table.containsKey(userId)){
//						tables.get(user_table.get(userId)).tell(mo);
//					}
					break;
				}
				case HeadType.DUNGON_PLAYER_MOVE_STATE_CHANGE_VALUE:
				{
					ClientToBattleServerPb.MoveStateChange msc = (MoveStateChange) mo.getData();
					int tableId = msc.getTableId();
					if (tables.containsKey(tableId)) {
						tables.get(tableId).tell(mo);
					}
//					int userId2 = msc.getId();
//					//把这个消息发到用户所在的房间
//					if(user_table.containsKey(userId2)){
//						tables.get(user_table.get(userId2)).tell(mo);
//					}
					break;
				}
				case HeadType.C2BS_BUILD_REQ_VALUE:
				{
					ClientToBattleServerPb.BuildReq buildReq = (BuildReq) mo.getData();
					int tableId = buildReq.getTableId();
					if (tables.containsKey(tableId)) {
						tables.get(tableId).tell(mo);
					}
					break;
				}
				case HeadType.C2BS_BUILD_REMOVE_REQ_VALUE:
				{
					ClientToBattleServerPb.BuildRemoveReq req = (BuildRemoveReq) mo.getData();
					int tableId = req.getTableId();
					if (tables.containsKey(tableId)) {
						tables.get(tableId).tell(mo);
					}
					break;
				}
				case HeadType.USER_SET_ATTACKTARGET_REQ_VALUE:
				{
					System.out.println("USER_SET_ATTACKTARGET_REQ_VALUE");
					UserSetAttackTargetReq req = (UserSetAttackTargetReq) mo.getData();
					int tableId = req.getTableId();
					if (tables.containsKey(tableId)) {
						tables.get(tableId).tell(mo);
					}
					break;
				}
				case HeadType.DUNGON_LOGOUT_VALUE:
				{
					ClientToBattleServerPb.Logout lgout = (ClientToBattleServerPb.Logout) mo.getData();
					int uid = lgout.getUserId();
					if (!user_table.containsKey(uid)) {
						break;
					}
					int tableid = user_table.get(uid);
					
					tables.get(tableid).tell(mo);
					//清除这个用户在哪个房间的数据
					user_table.remove(uid);
					//如果房间里已经没有用户了，就把这个房间清理掉
					if(!user_table.values().contains(tableid)){
						this.getContext().stop(tables.get(tableid)); 
						tables.remove(tableid);
						System.out.println("房间"+tableid+"关闭");
					}
					CharManager.getInstance().delCharacter(uid);
					break;
				}
				case com.bkbw.live.common.dataproto.BattleToDatabasePb.HeadType.DB2BS_CHARACTER_RESP_VALUE:
				{
					System.out.println("mo DB2BS_CHARACTER_RESP_VALUE");
					DB2BSCharacterResp resp = (DB2BSCharacterResp)mo.getData();
					int actorId = resp.getTableId();
					if (tables.containsKey(actorId)) {
						tables.get(actorId).tell(mo);
					}
					break;
				}
				case HeadType.C2BS_BAG_ITEM_DETAIL_REQ_VALUE: 
				{
					C2BSBagItemDetailReq req = (C2BSBagItemDetailReq)mo.getData();
					if (tables.containsKey(req.getTableId())) {
						tables.get(req.getTableId()).tell(mo);
					}
					break;
				}
				case HeadType.C2BS_DROP_BAG_ITEM_REQ_VALUE:
				{
					C2BSDropBagItemReq req = (C2BSDropBagItemReq)mo.getData();
					if (tables.containsKey(req.getTableId())) {
						tables.get(req.getTableId()).tell(mo);
					}
					break;
				}
				case com.bkbw.live.common.dataproto.BattleToDatabasePb.HeadType.DB2BS_DROP_BAG_ITEM_RESP_VALUE:
				{
					logger.debug("actor manager receive DB2BS_DROP_BAG_ITEM_RESP_VALUE");
					DB2BSDropBagItemResp resp = (DB2BSDropBagItemResp)mo.getData();
					int actorId = resp.getTableId();
					if (tables.containsKey(actorId)) {
						tables.get(actorId).tell(mo);
					}
					break;
				}
				case HeadType.C2BS_USE_BAG_ITEM_REQ_VALUE:
				{
					C2BSUseBagItemReq req = (C2BSUseBagItemReq)mo.getData();
					if (tables.containsKey(req.getTableId())) {
						tables.get(req.getTableId()).tell(mo);
					}
					break;
				}
				case com.bkbw.live.common.dataproto.BattleToDatabasePb.HeadType.DB2BS_USE_BAG_ITEM_RESP_VALUE:
				{
					System.out.println("mo DB2BS_USE_BAG_ITEM_RESP_VALUE");
					DB2BSUseBagItemResp resp = (DB2BSUseBagItemResp)mo.getData();
					int actorId = resp.getTableId();
					if (tables.containsKey(actorId)) {
						tables.get(actorId).tell(mo);
					}
					break;
				}
				case HeadType.C2BS_BUY_ITEM_REQ_VALUE:
				{
					C2BSBuyItemReq req = (C2BSBuyItemReq)mo.getData();
					if (tables.containsKey(req.getTableId())) {
						tables.get(req.getTableId()).tell(mo);
					}
					break;
				}
				case HeadType.C2BS_EQUIP_REQ_VALUE:
				{
					C2BSEquipReq req = (C2BSEquipReq)mo.getData();
					if (tables.containsKey(req.getTableId())) {
						tables.get(req.getTableId()).tell(mo);
					}
					break;
				}
				case com.bkbw.live.common.dataproto.BattleToDatabasePb.HeadType.DB2BS_BUY_ITEM_RESP_VALUE:
				{
					DB2BSBuyItemResp resp = (DB2BSBuyItemResp)mo.getData();
					if (tables.containsKey(resp.getTableId())) {
						tables.get(resp.getTableId()).tell(mo);
					}
					break;
				}
				case com.bkbw.live.common.dataproto.BattleToDatabasePb.HeadType.DB2BS_EQUIP_RESP_VALUE:
				{
					DB2BSEquipResp resp = (DB2BSEquipResp)mo.getData();
					if (tables.containsKey(resp.getTableId())) {
						tables.get(resp.getTableId()).tell(mo);
					}
					break;
				}
				case HeadType.C2BS_BUILD_MOVE_REQ_VALUE:
				{
					C2BSBuildMoveReq req = (C2BSBuildMoveReq)mo.getData();
					if (tables.containsKey(req.getTableId())) {
						tables.get(req.getTableId()).tell(mo);
					}
					break;
				}
				default:
				{
					break;
				}
				}
			}
			else if (arg0 instanceof AsyncPathRequest) {
				findPathActor.tell(arg0);
			}
			else if (arg0 instanceof AsyncPathResponse) {
				AsyncPathResponse resp = (AsyncPathResponse)arg0;
				if (tables.containsKey(resp.getTableId())) {
					tables.get(resp.getTableId()).tell(arg0);
				}
			}
		}
		catch (Exception e){
			e.printStackTrace();
		}
		
	}
	
	//桌子列表
	
	
	//启动一个桌子
	
	//由桌子来判断各个信息
}
